package com.wanlian.router.net.netty2.msg;

import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import com.wanlian.router.net.netty2.ConstantCode;
import com.wanlian.router.utils.JsonStringUtil;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.ByteToMessageDecoder;

import java.nio.charset.Charset;
import java.util.Arrays;
import java.util.List;

/**
 * 解码器
 *
 * @author ailianlu2
 */
public class PeerMsgDecoder extends ByteToMessageDecoder {

    final protected static char[] hexArray = "0123456789abcdef".toCharArray();

    @Override
    protected void decode(ChannelHandlerContext channelHandlerContext, ByteBuf byteBuf, List<Object> list) {
        try {
////            String msg = byteBuf.toString(Charset.defaultCharset());
////            System.out.println(Arrays.toString(hexStringToByteArray(msg)));
//
//            byte[] bodyxx = new byte[20];
//            byteBuf.readBytes(bodyxx);
//            printChar(bytesToHex(bodyxx));


            // 记录包头开始的index
            int beginReader;
            while (true) {
                // 获取包头开始的index
                beginReader = byteBuf.readerIndex();
                // 标记包头开始的index
                byteBuf.markReaderIndex();
                int data = byteBuf.readInt();
                // 读到了协议的开始标志，结束while循环
                if (data == ConstantCode.HEAD_DATA) {
                    break;
                }

                // 未读到包头，略过一个字节
                // 每次略过，一个字节，去读取，包头信息的开始标记
                byteBuf.resetReaderIndex();
                byteBuf.readByte();

                // 当略过，一个字节之后，
                // 数据包的长度，又变得不满足
                // 此时，应该结束。等待后面的数据到达
//            if (byteBuf.readableBytes() < BASE_LENGTH) {
//                return;
//            }
            }

            // 消息的长度
            int version = byteBuf.readInt();
            int msgtype = byteBuf.readInt();
            int length = byteBuf.readInt();
            // 判断请求数据包数据是否到齐
            if (byteBuf.readableBytes() < length) {
                // 还原读指针
                byteBuf.readerIndex(beginReader);
                return;
            }
            byte[] body = new byte[length];
            byteBuf.readBytes(body);
            if (msgtype == ConstantCode.COMMON_MSG) {
                String content = new String(body, Charset.forName("UTF-8"));
                BaseMsg baseMsg =  new Gson().fromJson(content, BaseMsg.class);
                if(baseMsg!=null) {
                    PeerMsg myMessage = new PeerMsg(new MsgHead(length, version, msgtype), baseMsg);
                    list.add(myMessage);
                }
            } else if (msgtype == ConstantCode.FILE_MSG) {
                PeerMsg myMessage = new PeerMsg();
                myMessage.setHead(new MsgHead(length, version, msgtype));
                String content = new String(body, Charset.forName("UTF-8"));
                FileBaseMsg baseMsg =  new Gson().fromJson(content, FileBaseMsg.class);//JsonStringUtil.readValue(content, new TypeToken<FileBaseMsg>().getType());
                myMessage.setFileBaseMsg(baseMsg);
                list.add(myMessage);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


    public static char[] bytesToHex(byte[] bytes) {
        char[] hexChars = new char[bytes.length * 2];
        for (int j = 0; j < bytes.length; j++) {
            int v = bytes[j] & 0xFF;
            hexChars[j * 2] = hexArray[v >>> 4];
            hexChars[j * 2 + 1] = hexArray[v & 0x0F];
        }
        return hexChars;
    }

    public static void printChar(char[]chars){
        System.out.print("[");
        for (int j = 0; j < chars.length; j=j+2) {
            System.out.print(chars[j]);
            if(j<chars.length-1) {
                System.out.print(chars[j + 1]);
                if(j<chars.length-2) {
                    System.out.print(",");
                }
            }
        }
        System.out.print("]");
        System.out.println();
        return ;
    }
}
